﻿//To Do log des recherches de series !!!!!!!!!!

using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Threading;
using System.Windows;
using System.Windows.Threading;
using Microsoft.WindowsAPICodePack.Taskbar;
using Serietheque.Fenetres;
using Serietheque.Properties;
using TvdbLib;
using TvdbLib.Cache;
using TvdbLib.Data;
using System.Text.RegularExpressions;

namespace Serietheque
{
    internal class Tvdb : IDisposable
    {
        private static string ApiKey = "3BF750A91C3C80F9";
        private TvdbHandler m_tvdbHandler;
        private string m_ft = Settings.Default.Cache + "\\log.txt";
        //private TvdbLanguage m_language = new TvdbLanguage(17, "Français", "fr");
        private TvdbLanguage m_language = TvdbLanguage.DefaultLanguage;

        public Tvdb()
        {
            XmlCacheProvider xmlCacheProvider = new XmlCacheProvider(Settings.Default.Cache);
            xmlCacheProvider.InitCache();
            m_tvdbHandler = new TvdbHandler(xmlCacheProvider, ApiKey);
            //m_tvdbHandler = new TvdbHandler(ApiKey);
            InitCache();
        }

        public Tvdb(string _apiKey)
        {

            XmlCacheProvider xmlCacheProvider = new XmlCacheProvider(Settings.Default.Cache);
            m_tvdbHandler = new TvdbHandler(xmlCacheProvider, _apiKey);
            //InitCache();
        }

        public void GetFullSeries()
        {
            //InitCache();
            List<int> list = m_tvdbHandler.GetCachedSeries();
            foreach (int item in list)
            {
                try
                {
                    m_tvdbHandler.GetFullSeries(item, m_language, false);
                }
                catch (Exception)
                {

                }
            }
            //CloseCache();
        }

        public TvdbSeries GetSerie(int _id)
        {
            //En Francais
            TvdbSeries serie;
            try
            {
                serie = m_tvdbHandler.GetBasicSeries(_id, m_language, false);
            }
            catch (Exception)
            {
                serie = null;
            }

            return serie;
        }

        public TvdbSeries GetSerieFull(int _id)
        {
            //En Francais
            //InitCache();
            TvdbSeries serieTvdb;
            try
            {
                serieTvdb = m_tvdbHandler.GetFullSeries(_id, m_language, false);
                serieTvdb = m_tvdbHandler.ForceReload(serieTvdb);
                //m_tvdbHandler.ForceReload(serie, true, false, false, false);
            }
            catch (Exception)
            {
                serieTvdb = null;
            }
            //CloseCache();

            return serieTvdb;
        }

        /// <summary>
        /// Chargé la banière voulu si besoin et retourne le chemin de celle ci
        /// </summary>
        /// <param name="_id">id de la actualSerie</param>
        /// <param name="_type">num de la saison</param>
        /// <returns></returns>
        public string LoadBanner(int _id, bool _copy = false)
        {

            string directoryPath = Settings.Default.Cache + "\\" + _id + "\\"; // directory
            string imgPath = ""; // path de base

            //on cherche si une image est presente            
            if (Directory.Exists(directoryPath))
            {
                string[] f = Directory.GetFiles(directoryPath, "*.jpg");
                if (f.Length >= 1)
                    imgPath = f[0];
            }

            if (String.IsNullOrWhiteSpace(imgPath))//si il n'y as pas encore d'image.
            {
                TvdbBanner banner = null;
                try
                {
                    m_tvdbHandler.GetFullSeries(_id, m_language, true);
                }
                catch (TvdbLib.Exceptions.TvdbException ex)
                {
                    ex.ToString();
                }

                TvdbSeries serie;

                //InitCache();
                m_tvdbHandler.InitCache();

                try
                {
                    serie = m_tvdbHandler.GetFullSeries(_id, m_language, true);
                }
                catch (TvdbLib.Exceptions.TvdbException ex)
                {
                    ex.ToString();
                    serie = null;
                }

                if (serie != null && serie.PosterBanners.Count > 0)
                    banner = serie.PosterBanners[0];
                var test1 = banner.LoadBanner();

                
                //CloseCache();


                if (banner != null)
                {
                    string[] test = banner.BannerPath.Split('/');
                    imgPath = Settings.Default.Cache + "\\" + _id + "\\" + "img_posters_" + test.GetValue(1);

                    if (!File.Exists(imgPath))
                    {
                        banner.LoadBanner();
                    }
                }
            }
            return imgPath;
        }

        public string GetImagePath(Series s)
        {
            string imagePath = Settings.Default.Cache + "//" + s.IdTvdb + "//";
            string[] img = null;

            if (s.IdTvdb.Value != 0)
            {

                this.LoadBanner(s.IdTvdb.Value, true);

                img = Directory.GetFiles(imagePath, "*.jpg");
            }
            if (img != null)
                if (img.Length != 0)
                    return img[0];
                else
                    return null;
            else
                return null;
        }

        private void InitCache()
        {
            m_tvdbHandler.InitCache();
        }

        private void CloseCache()
        {
            m_tvdbHandler.CloseCache();
        }

        public int GetSerieId(string nomSerie)
        {
            int id = SerieIdByLog(nomSerie);
            if (id == 0)
            {
                id = SerieIdByTvdb(nomSerie);
                if (id != 0)
                    using (StreamWriter sw = new StreamWriter(m_ft, true))
                        sw.WriteLine(nomSerie + "," + id);
            }

            return id;
        }

        public int SerieIdByTvdb(string nomSerie)
        {
            //InitCache();
            int id = 0;
            List<TvdbSearchResult> series = null;
            try
            {
                series = m_tvdbHandler.SearchSeries(nomSerie);
            }
            catch (Exception)
            {
                return 0; //throw;
            }

            if (series != null)
            {
                try
                {

                    if (series.Count == 1 && String.Compare(series[0].SeriesName, nomSerie) == 0)
                    {
                        id = series[0].Id;
                    }

                    else
                    {
                        TaskbarManager.Instance.SetProgressState(TaskbarProgressBarState.Paused);

                        //TO DO : if thread sinon
                        Application.Current.Dispatcher.Invoke(DispatcherPriority.Normal, (ThreadStart)delegate //Pour ouvrir sur un autre thread
                            {
                                ChoixSerie form = new ChoixSerie(series, nomSerie, m_tvdbHandler);
                                form.Topmost = true;
                                form.ShowDialog();
                                if (form.DialogResult == true)
                                    id = form.Selection.Id;
                                else
                                    id = 0;
                                TaskbarManager.Instance.SetProgressState(TaskbarProgressBarState.Normal);
                            });
                    }
                }
                catch (Exception)
                {
                    return 0;
                }
            }
            else
                id = 0;
            //CloseCache();
            return id;
        }

        private int SerieIdByLog(string nomSerie)
        {
            int id = 0;
            if (!File.Exists(m_ft))
            {
                // Create the file.
                using (FileStream fs = File.Create(m_ft))
                {
                    fs.WriteByte(new byte());
                }
            }
            try
            {
                using (StreamReader sr = new StreamReader(m_ft))
                {
                    string ligne = sr.ReadLine();
                    while (ligne != null)
                    {
                        if (String.Compare(nomSerie, ligne.Split(',')[0], true) == 0)
                            id = Int32.Parse(ligne.Split(',')[1], CultureInfo.InvariantCulture);
                        ligne = sr.ReadLine();
                    }
                }
            }
            catch { id = 0; }

            return id;
        }

        public string GetSerieName(int seriedId)
        {
            try
            {
                //InitCache();
                string retour = m_tvdbHandler.GetBasicSeries(seriedId, m_language, false).SeriesName;
                //CloseCache();
                return retour;
            }
            catch (Exception)
            {
                return "";
            }
        }

        /// <summary>
        /// mise a jours des infos de la serie.
        /// </summary>
        /// <param name="serie"></param>
        public void UpdateSerieData(Series serie)
        {
            //Tvdb tvdb = new Tvdb();
            TvdbSeries tvdbSerie = this.GetSerie((int)serie.IdTvdb);
            if (tvdbSerie != null)
            {
                serie.Name = tvdbSerie.SeriesName;
                serie.AirDay = tvdbSerie.AirsDayOfWeek.ToString();
                serie.Live = tvdbSerie.Status;
                serie.Overview = tvdbSerie.Overview;
                serie.ImagePath = this.LoadBanner((int)serie.IdTvdb, true);
            }
        }

        /// <summary>
        /// Obtient le name de l'episode
        /// </summary>
        /// <param name="_serieId">Id de la série</param>
        /// <param name="_numSaison">Numéro de saison</param>
        /// <param name="_numEpisode">Numéro de l'épisode</param>
        /// <returns>Name de l'épisode</returns>
        public string GetEpisodeName(int _serieId, int _numSaison, int _numEpisode)
        {
            try
            {
                //InitCache();
                string retour = m_tvdbHandler.GetEpisode(_serieId, _numSaison, _numEpisode, TvdbEpisode.EpisodeOrdering.DefaultOrder, TvdbLanguage.DefaultLanguage).EpisodeName;
                //CloseCache();
                return retour;
            }
            catch (Exception)
            {
                return null;
            }
        }

        /// <summary>
        /// Obtient le name de l'episode
        /// </summary>
        /// <param name="_episodeId">Id de l'épisode</param>
        /// <returns>Name de l'épisode</returns>
        public string GetEpisodeName(int _episodeId)
        {
            try
            {
                //InitCache();
                string r = m_tvdbHandler.GetEpisode(_episodeId, TvdbLanguage.DefaultLanguage).EpisodeName;
                //CloseCache();
                return r;
            }
            catch (Exception)
            {
                return null;
            }
        }

        /// <summary>
        /// Obtient des infos sur un épisode
        /// </summary>
        /// <param name="serieId">Id actualSerie</param>
        /// <param name="numSaison">numéro de la saison</param>
        /// <param name="numEpisode">numéro de l'épisode dans la saison</param>
        /// <returns>object[] { episodeId, saisonId, Name Episode, Air Date }</returns>
        public object[] GetEpisodeInfo(int serieId, int numSaison, int numEpisode)
        {
            try
            {
                //InitCache();
                if (m_tvdbHandler.IsCacheInitialised)
                { }
                //foreach (TvdbEpisode episode in m_tvdbHandler.GetBasicSeries(serieId, m_language, false).GetEpisodes(numSaison, TvdbEpisode.EpisodeOrdering.DefaultOrder))
                //    if (episode.EpisodeNumber == numEpisode)
                //    {   CloseCache();
                //   bb     return new object[] { episode.Id, episode.SeasonId, episode.EpisodeName, episode.FirstAired };
                //    }
                TvdbEpisode episode = m_tvdbHandler.GetEpisode(serieId, numSaison, numEpisode, TvdbEpisode.EpisodeOrdering.DefaultOrder, m_language);

                //CloseCache();
                return new object[] { episode.Id, episode.SeasonId, episode.EpisodeName, episode.FirstAired };
            }
            catch (Exception e)
            {
                return new[] { e.Message };
            }
        }
        /// <summary>
        /// update info de l'episode
        /// </summary>
        /// <param name="episode"></param>
        public void UpdateEpisodeData(Episodes episode)
        {
            object[] infoEpisode = this.GetEpisodeInfo((int)episode.Saisons.Series.IdTvdb, episode.Saisons.Num, episode.Num);
            if (infoEpisode.Length > 1)
            {
                DateTime date = (DateTime)infoEpisode[3];
                if (date == null)
                    date = DateTime.Now;
                if (date.Year == 1)
                    date = new DateTime(2001, 01, 01);
                episode.AirDate = date;
                episode.IdTvdb = Int32.Parse(infoEpisode[0].ToString(), CultureInfo.InvariantCulture);
                episode.Saisons.IdTvdb = Int32.Parse(infoEpisode[1].ToString(), CultureInfo.InvariantCulture);
                episode.Name = infoEpisode[2].ToString();
            }
            if (episode.AirDate == null)
                episode.AirDate = DateTime.Now;
            if (episode.AirDate.Value.Year == 1)
                episode.AirDate.Value.AddYears(2010);
        }



        public int GetSaisonId(int serieId, int saisonNum)
        {
            TvdbSeries s = m_tvdbHandler.GetSeries(serieId, m_language, false, false, false);
            return s.GetEpisodes(saisonNum)[0].SeasonId;
        }

        public void UpdateCache()
        {
            //InitCache();
            try
            {
                m_tvdbHandler.UpdateAllSeries();
            }
            catch (Exception)
            {

            }
            //CloseCache();
        }

        internal int GetSaisonId(int? nullable, int p)
        {
            throw new NotImplementedException();
        }

        void IDisposable.Dispose()
        {
            CloseCache();
        }
    }
}